package com.ultra.validator;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.ultra.exception.UnableResolveTypeException;
import com.ultra.factory.RandomArgumentFactory;
import com.ultra.reflect.ReflectUtil;
import com.ultra.resultset.DeepEquals;
import com.ultra.template.content.AcvContext;
import lombok.extern.slf4j.Slf4j;
import javax.script.ScriptException;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;

/**
 * @author yinger
 * @description 验证器
 * @date 2024/1/4 19:35
 **/
@Slf4j
public class Validator {
    private static final int MAX_VERIFICATION_TIMES = 10_0000;
    /**
     * 验证函数
     *
     * @param context 验证器配置对象
     * @return 验证结果，true表示验证通过，false表示验证不通过
     * @throws IllegalArgumentException 如果配置不正确抛出异常
     */
    protected boolean verification(AcvContext context) throws IllegalArgumentException, JsonProcessingException, UnableResolveTypeException, ClassNotFoundException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchMethodException, ScriptException {
        if (context.getTestTimes() > MAX_VERIFICATION_TIMES) {
            throw new IllegalArgumentException("验证次数过多 ... ");
        }
        long correctTakeTime = 0;
        long validatorTakeTime = 0;
        // TODO before
        for (int i = 0; i < context.getTestTimes(); i++) {
            Object[][] test = RandomArgumentFactory.factorytDispatcher(context);
            // TODO after
            long startValidatorTime = System.currentTimeMillis();
            Object result1 = ReflectUtil.invoke(context.getValidatorMethod(), test[0]);
            validatorTakeTime += System.currentTimeMillis() - startValidatorTime;

            long startCorrectTime = System.currentTimeMillis();
            Object result2 = ReflectUtil.invoke(context.getCorrectMethod(), test[1]);
            correctTakeTime += System.currentTimeMillis() - startCorrectTime;
            if (!DeepEquals.deepEquals(result1, result2,context.getValidatorMethod())) {
                System.out.println(Arrays.deepToString(test[0]));
                System.out.println(Arrays.deepToString(test[1]));
                log.error("验证第{}次失败", i + 1);
                return false;
            }
            log.info("第{}次验证通过", i + 1);
        }
        log.info("validator method take time: {} ms", validatorTakeTime);
        log.info("correct method take time: {} ms", correctTakeTime);
        return true;
    }

}
